home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dr. Windows 3
/
dr win3.zip
/
dr win3
/
PROGRAMR
/
OLE2BOOK.ZIP
/
CHAP05.ZIP
/
CHAP05
/
POLYLINE
/
IPOLYLIN.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-06-17
|
22KB
|
1,003 lines
/*
* IPOLYLIN.CPP
* Modifications for Chapter 5.
*
* Implementation of the IPolyline interface that we expose on the
* CPolyline object.
*
* Copyright (c)1993 Microsoft Corporation, All Rights Reserved
*
* Kraig Brockschmidt, Software Design Engineer
* Microsoft Systems Developer Relations
*
* Internet : kraigb@microsoft.com
* Compuserve: >INTERNET:kraigb@microsoft.com
*/
#include "polyline.h"
/*
* CImpIPolyline:CImpIPolyline
* CImpIPolyline::~CImpIPolyline
*
* Constructor Parameters:
* pObj LPVOID pointing to the object we live in.
* punkOuter LPUNKNOWN of the controlling unknown.
*/
CImpIPolyline::CImpIPolyline(LPVOID pObj, LPUNKNOWN punkOuter)
{
m_cRef=0;
m_pObj=pObj;
m_punkOuter=punkOuter;
return;
}
CImpIPolyline::~CImpIPolyline(void)
{
return;
}
/*
* CImpIPolyline::QueryInterface
* CImpIPolyline::AddRef
* CImpIPolyline::Release
*
* Purpose:
* Standard set of IUnknown members for this interface
*/
STDMETHODIMP CImpIPolyline::QueryInterface(REFIID riid, LPVOID FAR *ppv)
{
return m_punkOuter->QueryInterface(riid, ppv);
}
STDMETHODIMP_(ULONG) CImpIPolyline::AddRef(void)
{
++m_cRef;
return m_punkOuter->AddRef();
}
STDMETHODIMP_(ULONG) CImpIPolyline::Release(void)
{
--m_cRef;
return m_punkOuter->Release();
}
/*
* CImpIPolyline::Init
*
* Purpose:
* Instantiates a polyline window within a given parent. The
* parent may be a main application window, could be an MDI child
* window. We really do not care.
*
* Parameters:
* hWndParent HWND of the parent of this window
* pRect LPRECT that this window should occupy
* dwStyle DWORD containing the window's style flags
* uID UINT ID to associate with this window
*
* Return Value:
* HRESULT NOERROR if successful, otherwise E_OUTOFMEMORY
*/
STDMETHODIMP CImpIPolyline::Init(HWND hWndParent, LPRECT pRect
, DWORD dwStyle, UINT uID)
{
LPCPolyline pObj=(LPCPolyline)m_pObj;
SCODE sc;
pObj->m_hWnd=CreateWindowEx(WS_EX_NOPARENTNOTIFY, SZCLASSPOLYLINE
, SZCLASSPOLYLINE, dwStyle, pRect->left, pRect->top
, pRect->right-pRect->left, pRect->bottom-pRect->top
, hWndParent, (HMENU)uID, pObj->m_hInst, (LPVOID)pObj);
sc=(NULL!=pObj->m_hWnd) ? S_OK : E_OUTOFMEMORY;
return ResultFromScode(sc);
}
//CHAPTER5MOD
/*
* ::ReadFromFile and ::WriteToFile are replaced by the IPersistStorage
* implementation. We no longer read from files, instead we use
* storages.
*/
//End CHAPTER5MOD
/*
* CImpIPolyline::DataSet
*
* Purpose:
* Sets the current data in this Polyline to a given structure.
*
* Parameters:
* pplIn LPPOLYLINEDATA to initialize to.
* fSizeToData BOOL indicating if we're to size to the data or scale it.
* fNotify BOOL indicating if we're to send an advise on this change.
*
* Return Value:
* HRESULT NOERROR if successful, otherwise a POLYLINE_E_ value.
*/
STDMETHODIMP CImpIPolyline::DataSet(LPPOLYLINEDATA pplIn, BOOL fSizeToData
, BOOL fNotify)
{
LPCPolyline pObj=(LPCPolyline)m_pObj;
LPPOLYLINEDATA ppl=&pObj->m_pl;
RECT rc;
/*
* Copy the structure in pplIn and repaint to reflect the new point
* set. Note that unlike the RectSet message, we do no scaling,
* assuming that the rect in the structure is appropriate for the data.
*/
if (NULL==pplIn)
return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
//Preserve the old rectangle, then copy
rc=ppl->rc;
*ppl=*pplIn;
//Inform our parent of the data change
if (NULL!=pObj->m_pAdv)
{
pObj->m_fDirty=TRUE;
pObj->m_pAdv->OnDataChange();
}
/*
* If we're scaling the window to fit the data, then use
* RectSet passing our current rectangle as the new one.
* That makes sure that the data won't change but that the
* window is resized.
*/
if (fSizeToData)
{
POINT pt;
/*
* Get our offset in the parent window so we can RectSet
* to the right place since RectSet expects rectangle in
* parent coordinates and we get it in client coordinates.
*/
GetWindowRect(pObj->m_hWnd, &rc);
pt.x=rc.left;
pt.y=rc.top;
ScreenToClient(GetParent(pObj->m_hWnd), &pt);
rc=ppl->rc;
OffsetRect(&rc, pt.x, pt.y);
//This will also cause a repaint.
RectSet(&rc, fNotify);
}
else
{
//Make sure we're updated.
InvalidateRect(pObj->m_hWnd, NULL, TRUE);
UpdateWindow(pObj->m_hWnd);
}
return NOERROR;
}
/*
* CImpIPolyline::DataGet
*
* Purpose:
* Retrieves the Polyline's current data.
*
* Parameters:
* pplIn LPPOLYLINEDATA into which we copy the data.
*
* Return Value:
* HRESULT NOERROR if successful, otherwise a POLYLINE_E_ value.
*/
STDMETHODIMP CImpIPolyline::DataGet(LPPOLYLINEDATA pplIn)
{
LPCPolyline pObj=(LPCPolyline)m_pObj;
if (NULL==pplIn)
return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
*pplIn=pObj->m_pl;
return NOERROR;
}
/*
* CImpIPolyline::DataSetMem
*
* Purpose:
* Sets the Polyline's data using a global memory handle
* instead of a pointer.
*
* Parameters:
* hMem HGLOBAL containing the data.
* fFree BOOL indicating if we're to free the data. The memory
* will be freed regardless of any error returned from here.
* fSizeToData BOOL indicating if we're to size to the data or scale it.
* fNotify BOOL indicating if we're to send an advise on this change.
*
* Return Value:
* HRESULT NOERROR if successful, otherwise a POLYLINE_E_ value.
*/
STDMETHODIMP CImpIPolyline::DataSetMem(HGLOBAL hMem, BOOL fFree
, BOOL fSizeToData, BOOL fNotify)
{
LPPOLYLINEDATA ppl;
HRESULT hr=ResultFromScode(POLYLINE_E_INVALIDPOINTER);
if (NULL!=hMem)
{
ppl=(LPPOLYLINEDATA)GlobalLock(hMem);
hr=DataSet(ppl, fSizeToData, fNotify);
GlobalUnlock(hMem);
if (fFree)
GlobalFree(hMem);
}
return hr;
}
/*
* CImpIPolyline::DataGetMem
*
* Purpose:
* Retrieves the Polyline's data in a global memory handle.
*
* Parameters:
* phMem HGLOBAL FAR * in which to store the handle.
*
* Return Value:
* HRESULT NOERROR if successful, otherwise a POLYLINE_E_ value.
*/
STDMETHODIMP CImpIPolyline::DataGetMem(HGLOBAL FAR *phMem)
{
HGLOBAL hMem;
LPPOLYLINEDATA ppl;
HRESULT hr=ResultFromScode(POLYLINE_E_INVALIDPOINTER);
if (NULL==phMem)
return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
hMem=GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, CBPOLYLINEDATA);
if (NULL!=hMem)
{
ppl=(LPPOLYLINEDATA)GlobalLock(hMem);
hr=DataGet(ppl);
GlobalUnlock(hMem);
if (FAILED(hr))
{
GlobalFree(hMem);
hMem=NULL;
}
}
*phMem=hMem;
return hr;
}
/*
* CImpIPolyline::RenderBitmap
*
* Purpose:
* Creates a bitmap image of the current Polyline.
*
* Parameters:
* phBmp HBITMAP FAR * in which to return the bitmap.
*
* Return Value:
* HRESULT NOERROR if successful, otherwise a POLYLINE_E_ value.
*/
STDMETHODIMP CImpIPolyline::RenderBitmap(HBITMAP FAR *phBmp)
{
LPCPolyline pObj=(LPCPolyline)m_pObj;
HDC hDC;
HDC hMemDC;
HBITMAP hBmp;
RECT rc;
HGDIOBJ hObj;
if (NULL==phBmp)
retu